package futbol.tacticas.concursantes.qualitycode.ctrlteam;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import futbol.tacticas.Comando;
import futbol.tacticas.ComandoGolpearBola;
import futbol.tacticas.ComandoIrA;
import futbol.tacticas.ComandoTiroAPuerta;
import futbol.tacticas.concursantes.qualitycode.QCodeTactica;
import futbol.tacticas.concursantes.qualitycode.common.QBall;
import futbol.tacticas.concursantes.qualitycode.common.QPlayer;
import futbol.tacticas.concursantes.qualitycode.common.QUtils;
import futbol.tacticas.concursantes.qualitycode.ctrlteam.QPases.TipoPase;
import futbol.tacticas.concursantes.qualitycode.opponent.QOpponentPlayer;

public class QCtrlPlayer extends QPlayer
{
  public enum Area {DELANTE, CENTRO, ATRAS};
  public enum Funcion { CONTROLADOR,SOPORTE,DELANTERO,  
                        RECUPERA_DELANTERO,RECUPERA_DEFENSA, DEFENSA, PORTERO};
  
  private final Point start = new Point(QCodeTactica.INVALID, QCodeTactica.INVALID);
  private final List<Comando> comandos = new ArrayList<Comando>();
  private QCtrlTeam team;
  
  private final Funcion basica;
  private Funcion funcion;
  
  private QPases pase = null;
  private boolean pasoAotro = false;
  private QPases.TipoPase ultimoPase = null;
  
//---------------------------------------------------------------  
  
  public QCtrlPlayer(QCtrlTeam team, int id, Funcion funcion)
  {
    super(id);
    this.team = team;
    this.funcion = funcion;
    this.basica  = funcion;
  }

  public QCtrlPlayer(QCtrlPlayer player)
  {
    super(player);    
    this.start.setLocation(player.start);
    this.team = player.team;
    this.basica = player.basica;
    this.funcion = player.funcion;    
  }

  public boolean isPasoAotro()
  {
    return pasoAotro;
  }

  public void resetPasoAotro()
  {
    pasoAotro = false;
  }

  public void resetFuncion()
  {
    funcion = basica;
  }

  public void setFuncion(Funcion newFuncion)
  {
    funcion = newFuncion;
  }

  public void reset()
  {
    super.reset();
    x = start.x;
    y = start.y;
    pasoAotro = false;
    funcion = basica;
  }

  public boolean isFuncion(Funcion funcion)
  {
    return this.funcion == funcion;
  } 
  
  public void setup(Point start, int force)
  {
    this.start.setLocation(start);
    this.force = force;
    x = start.x;
    y = start.y;
  }

  public Point getStart()
  {
    return new Point(start);
  }

  public void exec()
  {
    if (team.isControlador(this)) 
    {
      if (pase == null)
        pase = new QPases(this, team);
      else
        pase.reset();
        
        QPase.start(team, this, team.getBall());
    }
    else
    {
      pase = null;
    }
  }

  @Override
  public void updatePos(Point point)
  {
    super.updatePos(point);
    pase = null;
  }
//-------------------------------------------------------------------
  
  public boolean cmdInterseptarBola()
  {
    final Point dest = interseptarBola(team.getBall().getFutureBalls()).getPos();
    comandos.add(new ComandoIrA(id, dest.x, dest.y));
    return true;
  }

  public boolean cmdGolpearBolaForsado(QBall ball, Point dest)
  {
    comandos.add(new ComandoGolpearBola(getID(), dest.x, dest.y));
    team.getBall().golpearBola(this, dest.x, dest.y);
    return true;
  }
  
  public boolean cmdGolpearBola(QBall ball, Point dest)
  {
    if (canGolpear(ball))
    {
      comandos.add(new ComandoGolpearBola(getID(), dest.x, dest.y));
      team.getBall().golpearBola(this, dest.x, dest.y);
      return true;
    }
    return false;
  }
  
  public boolean cmdIrA(Point dest)
  {
    comandos.add(new ComandoIrA(getID(), dest.x, dest.y));
    return true;
  }

//-------------------------------------------------------------------
  
  public List<Comando> getComandos()
  {
    return comandos;
  }

  public void clearComandos()
  {
    comandos.clear();
  }

//-------------------------------------------------------------------
  
  public boolean canEsperar()
  {
    final List<? extends QPlayer> oppoents = team.getOpponentTeam().cercania(this);
    if (oppoents.get(0).distance(this) > QBall.KICK_RADIO *2)      
      return true;
    
    return false;
  }

  public boolean hasPase(TipoPase tipo)
  {
    if (pase == null)
      pase = new QPases(this, team);
    
    return pase.pase(team, tipo) != null;
  }

  public void pasar(TipoPase tipo)
  {
    final QPlayer recibidor;
    if (pase.pase(team,tipo) != null)
      recibidor = pase.pase(team,tipo);
    else
    {      
      //System.out.println("[QCtrlPlayer.pase()] ANY");
      recibidor = pase.pase(team,TipoPase.ANY);      
    }
    
    //if (recibidor == null)
    //System.out.println("[QCtrlPlayer.pase()] " + (getID()+1) + "->" + (recibidor.getID()+1));
        
    ultimoPase = tipo;
    cmdGolpearBola(team.getBall(), recibidor.getPos());
    team.setControler(team.getPlayer(recibidor.getID()));
    if (pase.isAutoPase(tipo))     
      cmdIrA(recibidor.getPos());
    else
      pasoAotro = true;
  }

  public void soporte()
  {
    
  }

  public void pararBola()
  {
    if (team.getBall().getSpeed() > 1)
      cmdGolpearBola(team.getBall(), getPos());
  }

  public boolean canPase(TipoPase tipoPase)
  {
    return hasPase(tipoPase);
  }

  public void pasar()
  {
    final TipoPase[] orden = {TipoPase.LARGO_ADELANTE,
                              TipoPase.ADELANTE,
                              TipoPase.AUTO_ADELANTE,
                              TipoPase.AUTO_ATRAS,
                              TipoPase.ATRAS,
                              TipoPase.LARGO_ATRAS,
                              TipoPase.ANY,
                              };
    
    for (TipoPase tipoPase : orden)
    {
      if (hasPase(tipoPase))
      {        
        pasar(tipoPase);        
        break;
      }
    }
  }

  public void moveSoporte(QCtrlPlayer controlador)
  {
    controlador.canPase(this);
  }

  private void canPase(QCtrlPlayer ctrlPlayer)
  {
    if (!pase.hasPase(ctrlPlayer))
    {
      List<Point> points = new ArrayList<Point>();
      points.addAll(QPases.AUTO_ADELANTE);
      points.addAll(QPases.AUTO_ATRAS);
      
      for (Point p : points)
      {
        for (int i = 5; i >= 0; i--)
        {
          QPlayer fPlayer = ctrlPlayer.futurePos(p, i);
          if (pase.hasPase(fPlayer))
          {
            ctrlPlayer.cmdIrA(fPlayer.getPos());
            return;
          }
          else
            fPlayer.move();        
        }
      }
    }
  }

  public boolean puedeAnotar(QBall ball)
  {
    if (getX() >= 60 && canGolpear(ball)) 
    {
      if (canPase(QPases.TipoPase.ADELANTE))
        return false;

      //final double maxDesvio = 1 * Math.PI / 5 - Math.PI / 10;
      final QBall gBall = new QBall(ball);
      gBall.golpearBola(this, 180, 0);
      List<? extends QPlayer> oppponents = team.getOpponentTeam().getPlayers();
      oppponents = QUtils.filtrar(oppponents, this.getPos(), QUtils.Filter.ADELANTE);
      
      //QPlayer opponet = oppponents.get(0).futurePos(ball.getPos(), 0);
      for (QBall fBall : gBall.getFutureBalls())
      {
        if (fBall.isGoal() != -1)
          return true;
        
        if (fBall.isKickAble())// && opponet.canGolpear(fBall))
          return false;
      }
    }
    return false;
  }
  
  public boolean cmdTirarAMarco(QBall ball)
  {
    //cmdGolpearBola(team.getBall(), new Point(0,1000));
    comandos.add(new ComandoTiroAPuerta(getID(), 0));
    return false;
  }

  public boolean lastAutoPase()
  {
    return pase.isAutoPase(ultimoPase);
  }
  
  public void nuevoControlador()
  {
    ultimoPase = null;
  }

}



















